package com.atguigu.gulimall.product;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession;

/**
 * 1、整合mybatis-plus
 * 1>导入依赖
 * <dependency>
 * <groupId>com.baomidou</groupId>
 * <artifactId>mybatis-plus-boot-starter</artifactId>
 * <version>3.2.0</version>
 * </dependency>
 * 2》、配置
 * 2.1 配置数据源
 * 1>导入数据库驱动，（这里放到公共的common模块下）
 * 2》在 application.yml配置数据源相关信息
 * 2.2 配置mybatis-plus
 * 1>使用 @MapperScan
 * 2、逻辑删除
 * 1）、配置全局的逻辑删除规则（省略）
 * 2）、配置逻辑删除组件 Bean（省略）
 * 3）、姐bean上加上逻辑删除注解
 * 3、JSR303
 * 1）、给Bean添加校验注解：javax.validation.constraints，并定义自己的Message提示
 * 2）、开启校验注解 @Valid
 * 效果：校验错误后会有默认提示
 * 3）、给校验的Bean后面紧跟一个BindingResult，就可以获取到校验的结果
 * 4）、分组校验
 * 1) 添加分组接口AddGroup和UpdateGroup（不需要任何实现，这里写在了common组件中）
 * 2） @NotBlank(message = "品牌名必须提交",groups = {AddGroup.class,UpdateGroup.class})
 * 给校验注解标注什么情况需要校验
 * 3) @Validated({ AddGroup.class}) 标注在要校验的参数上     解析：valid是java规范  Validated是spring整合valid
 * 4)默认没有指定分组的校验注解@NotBlank，在分组情况下不生效，只会在 @Validated   不标注分组情况下生效
 * <p>
 * 5) 自定义校验
 * 1）编写一个自定义注解
 * 2）编写一个自定义校验器  ConstraintValidator
 * 3）关联自定义的校验器和自定义校验注解
 *
 * @Documented
 * @Constraint(validatedBy = { ListValueConstraintValidator.class【可以指定不同的校验器，适配 不同类型的校验】)
 * @Target({ METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER, TYPE_USE })
 * @Retention(RUNTIME) public @interface ListValue {
 * <p>
 * 4、统一的异常处理
 * @ControllerAdvice
 *
 *5、模版引擎
 * 1）thymeleaf-starter：关闭缓存
 * 2）静态资源放在static文件下就可以直接访问
 * 3）页面放在templates下也可以直接访问
 *     Springboot，访问项目的时候，默认会找index
 *  WebMvcAutoConfiguration--查看相应的配置
 *  4)、页面实时更新，不重启服务器
 *      dev-tools  导入依赖  注意加   <optional>true</optional>
 *      修改完页面control+f9  或者control+shift+f9
 *      如果代码配置，还是要重启项目
 *
 * 6、整合redis
 *  1)、引入>spring-boot-starter-data-redis
 *  2)、简单的配置redis等信息  （RedisAutoConfiguration 配置文件查看）
 *  3）、使用springBoot自动配置好的 StringRedisTemplate
 *     redis->map :存放数据key,数据值value
 *
 *  7、整合reddison作为分布式锁等功能框架
 *  1）引入依赖：
 *          <dependency>
 *             <groupId>org.redisson</groupId>
 *             <artifactId>redisson</artifactId>
 *             <version>3.12.0</version>
 *         </dependency>
 *    2、配合redisson
 *
 *  8、整合springCache简化缓存开发
 *      1)、引入依赖 spring-boot-starter-cache    spring-boot-starter-data-redis（用redis作为缓存）
 *      2）、写配置
 *       （1）、自动配置了哪些
 *          CacheAutoConfiguration会导入RedisCacheConfiguration
 *          自动配置好了缓存管理器  RedisCacheManager
 *        （2）、配置使用redis作为缓存
 *        spring.cache.type=redis
 *      3）、测试使用redis作为缓存
 *              @Cacheable: Triggers cache population.  触发将数据保存到缓存的操作
             * @CacheEvict: Triggers cache eviction.     触发将数据从缓存中删除的操作  失效模式使用
             * @CachePut: Updates the cache without interfering with the method execution.  不影响方法执行更新缓存  双写模式 需要有返回值
             * @Caching: Regroups multiple cache operations to be applied on a method.  组合以上多个操作
             * @CacheConfig: Shares some common cache-related settings at class-level.  在同一个类上共享缓存的相同的配置
 *         1)、开启缓存功能  @EnableCaching
 *         2）、只需要使用注解就能完成缓存操作
 *      4）原理：
 *      CacheAutoConfiguration -》 RedisCacheConfiguration-》
 *      自动配置了RedisCacheManager-》初始化所有的缓存-》每个缓存决定使用什么配置-》如果redisCacheConfiguration有就用，没有就用默认配置
 *      -》想改缓存的配置，只需要给容器中放一个RedisCacheConfiguration即可-》就会应用到当前RedisCacheManager管理的所有缓存分区中
 */

@EnableRedisHttpSession
@EnableFeignClients(basePackages = "com.atguigu.gulimall.product.feign")
@EnableDiscoveryClient
@MapperScan("com.atguigu.gulimall.product.dao")
@SpringBootApplication
public class GulimallProductApplication {

    public static void main(String[] args) {
        SpringApplication.run(GulimallProductApplication.class, args);
    }

}
